package com.demo.controller.admin;

import com.demo.dao.UserDao;
import com.demo.entity.User;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.PageRequest;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.IntStream;

import static org.junit.jupiter.api.Assertions.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

@SpringBootTest
@AutoConfigureMockMvc
@ActiveProfiles("test")
@Transactional
class AdminUserControllerIT {

    @Autowired
    private MockMvc mockMvc;

    @Autowired
    private UserDao userDao;

    private final int PAGE_SIZE = 10;
    private final int TOTAL_USERS = 25;
    private List<Integer> generatedUserIds = new ArrayList<>();

    @BeforeEach
    void setUp() {
        // 清空并初始化测试数据
        userDao.deleteAll();

        // 插入用户测试数据
        IntStream.rangeClosed(1, TOTAL_USERS).forEach(i -> {
            User user = new User();
            user.setUserID("testUser" + i);
            user.setUserName("测试用户" + i);
            user.setPassword("password" + i);
            user.setEmail("user" + i + "@example.com");
            user.setPhone("1380013800" + i);
            user.setIsadmin(i == 1 ? 1 : 0); // 第一个用户是管理员
            user.setPicture("/images/avatar" + i + ".jpg");
            User savedUser = userDao.save(user);
            generatedUserIds.add(savedUser.getId());
        });

        // 添加验证
        long count = userDao.count();
        System.out.println("Inserted users count: " + count);
        assertTrue(count > 0, "测试数据未正确插入");
    }

    @Test
    void userManage_ShouldShowCorrectTotalPages() throws Exception {
        // AdminUserController.user_manage只返回非管理员用户
        int nonAdminUsers = TOTAL_USERS - 1; // 非管理员用户数量
        int expectedPages = (int) Math.ceil((double) nonAdminUsers / PAGE_SIZE);

        mockMvc.perform(get("/user_manage"))
                .andExpect(status().isOk())
                .andExpect(model().attributeExists("total"))
                .andExpect(model().attribute("total", expectedPages));
    }

    @Test
    void userList_ShouldReturnPaginatedResults() throws Exception {
        // AdminUserController.userList只返回非管理员用户（isadmin=0）
        int nonAdminUsers = TOTAL_USERS - 1; // 非管理员用户数量
        
        mockMvc.perform(get("/userList.do").param("page", "1"))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$").isArray())
                .andExpect(jsonPath("$.length()").value(Math.min(PAGE_SIZE, nonAdminUsers)));
    }

    @Test
    void userList_ShouldReturnPaginatedResultsLastPage() throws Exception {
        // AdminUserController.userList只返回非管理员用户（isadmin=0）
        // 我们在测试中将第一个用户设为管理员，所以实际非管理员用户数量为TOTAL_USERS-1
        int nonAdminUsers = TOTAL_USERS - 1; // 非管理员用户数量
        int lastPage = (int) Math.ceil((double) nonAdminUsers / PAGE_SIZE);
        int lastPageSize = nonAdminUsers % PAGE_SIZE == 0 ? PAGE_SIZE : nonAdminUsers % PAGE_SIZE;

        // 输出调试信息
        System.out.println("Total users: " + TOTAL_USERS);
        System.out.println("Non-admin users: " + nonAdminUsers);
        System.out.println("Page size: " + PAGE_SIZE);
        System.out.println("Last page: " + lastPage);
        System.out.println("Expected last page size: " + lastPageSize);

        mockMvc.perform(get("/userList.do").param("page", String.valueOf(lastPage)))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$").isArray())
                .andExpect(jsonPath("$.length()").value(lastPageSize));
    }

    @Test
    void userAdd_ShouldReturnCorrectView() throws Exception {
        mockMvc.perform(get("/user_add"))
                .andExpect(status().isOk())
                .andExpect(view().name("admin/user_add"));
    }

    @Test
    void userEdit_ShouldReturnCorrectUserData() throws Exception {
        int userId = generatedUserIds.get(0);
        User user = userDao.findById(userId);
        
        mockMvc.perform(get("/user_edit").param("id", String.valueOf(userId)))
                .andExpect(status().isOk())
                .andExpect(view().name("admin/user_edit"))
                .andExpect(model().attributeExists("user"))
                .andExpect(model().attribute("user", user));
    }

    @Test
    void checkUserID_ShouldReturnTrueWhenUserIDNotExists() throws Exception {
        String userID = "newUserThatDoesNotExist";

        mockMvc.perform(post("/checkUserID.do").param("userID", userID))
                .andExpect(status().isOk())
                .andExpect(content().string("true"));
    }

    @Test
    void checkUserID_ShouldReturnFalseWhenUserIDExists() throws Exception {
        String userID = "testUser1"; // 这是setUp中创建的用户

        mockMvc.perform(post("/checkUserID.do").param("userID", userID))
                .andExpect(status().isOk())
                .andExpect(content().string("false"));
    }

    @Test
    void addUser_ShouldCreateUserInDatabase() throws Exception {
        String userID = "newTestUser";
        String userName = "新测试用户";
        String password = "newpassword";
        String email = "newtest@example.com";
        String phone = "13800001234";

        // 确保用户ID不存在
        assertEquals(0, userDao.countByUserID(userID));

        // 执行添加用户
        mockMvc.perform(post("/addUser.do")
                .param("userID", userID)
                .param("userName", userName)
                .param("password", password)
                .param("email", email)
                .param("phone", phone))
                .andExpect(status().is3xxRedirection())
                .andExpect(redirectedUrl("user_manage"));

        // 验证用户已添加到数据库
        assertEquals(1, userDao.countByUserID(userID));
        User addedUser = userDao.findByUserID(userID);
        assertNotNull(addedUser);
        assertEquals(userName, addedUser.getUserName());
        assertEquals(password, addedUser.getPassword());
        assertEquals(email, addedUser.getEmail());
        assertEquals(phone, addedUser.getPhone());
    }

    @Test
    void modifyUser_ShouldUpdateUserInDatabase() throws Exception {
        // 获取现有用户
        User existingUser = userDao.findByUserID("testUser2");
        assertNotNull(existingUser);
        int userId = existingUser.getId();

        // 新的用户信息
        String newUserID = "testUser2_updated";
        String newUserName = "更新的用户2";
        String newPassword = "updatedpassword";
        String newEmail = "updated2@example.com";
        String newPhone = "13900000002";

        // 执行修改用户
        mockMvc.perform(post("/modifyUser.do")
                .param("userID", newUserID)
                .param("oldUserID", existingUser.getUserID())
                .param("userName", newUserName)
                .param("password", newPassword)
                .param("email", newEmail)
                .param("phone", newPhone))
                .andExpect(status().is3xxRedirection())
                .andExpect(redirectedUrl("user_manage"));

        // 验证用户已更新
        User updatedUser = userDao.findById(userId);
        assertNotNull(updatedUser);
        assertEquals(newUserID, updatedUser.getUserID());
        assertEquals(newUserName, updatedUser.getUserName());
        assertEquals(newPassword, updatedUser.getPassword());
        assertEquals(newEmail, updatedUser.getEmail());
        assertEquals(newPhone, updatedUser.getPhone());
    }

    @Test
    void delUser_ShouldRemoveUserFromDatabase() throws Exception {
        // 获取一个用户ID
        int userId = generatedUserIds.get(3); // 使用第4个用户，避免使用管理员用户
        
        // 确认用户存在
        assertNotNull(userDao.findById(userId));

        // 执行删除操作
        mockMvc.perform(post("/delUser.do").param("id", String.valueOf(userId)))
                .andExpect(status().isOk())
                .andExpect(content().string("true"));

        // 验证用户已从数据库中删除
        assertNull(userDao.findById(userId));
    }

    @Test
    void userList_ShouldReturnAllUsersWithCorrectFields() throws Exception {
        mockMvc.perform(get("/userList.do").param("page", "1"))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$[0].id").exists())
                .andExpect(jsonPath("$[0].userID").exists())
                .andExpect(jsonPath("$[0].userName").exists())
                .andExpect(jsonPath("$[0].email").exists())
                .andExpect(jsonPath("$[0].phone").exists());
    }

    @Test
    void userList_ShouldReturnCorrectSortOrder() throws Exception {
        // 由于AdminUserController.userList只返回非管理员用户（isadmin=0）
        // 我们期望返回的第一个用户是testUser2（因为testUser1是管理员）
        int nonAdminUserIndex = 1; // testUser2对应的索引（索引从0开始，非管理员的第一个是索引1）
        int expectedFirstUserId = generatedUserIds.get(nonAdminUserIndex);
        
        mockMvc.perform(get("/userList.do").param("page", "1"))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$[0].id").value(expectedFirstUserId));
    }
} 